#include "assert.h"
#include "error.h"
#include"utils.h"
#include "string.h"

#include "fs/deffs.h"
#include "fs/iobuf.h"

#include "dbg.h"

iobuf_t*
iobuf_init(iobuf_t* iob, void* base, size_t len, offset_t offset) {
    iob->io_base = base;
    iob->io_len = iob->io_resid = len;
    iob->io_off = offset;
    return iob;
}

/**
 * @brief
 *
 * @param iob
 * @param data
 * @param len
 * @param m2b 1 - memory to buffer, 0 - buffer to mem
 * @param copied_store
 * @return int
 */
int
iobuf_move(iobuf_t* iob, void* data, size_t len, bool m2b, size_t* copied_store) {
    size_t _len = __MIN(iob->io_resid, len);
    if (_len > 0) {
        if (m2b)  // memory to buffer
            memmove(iob->io_base, data, _len);
        else
            memmove(data, iob->io_base, _len);
        iobuf_skip(iob, _len);
        len -= _len;
    }
    if (copied_store != NULL)
        *copied_store = _len;
    return (len == 0) ? 0 : -E_NO_MEM;
}

int
iobuf_moveZeros(iobuf_t* iob, size_t len, size_t* copied_store) {
    size_t _len = __MIN(iob->io_resid, len);
    if (_len > 0) {
        memset(iob->io_base, 0, _len);
        iobuf_skip(iob, _len);
        len -= _len;
    }
    if (copied_store != NULL)
        *copied_store = _len;
    return (len == 0) ? 0 : E_NO_MEM;
}

void
iobuf_skip(iobuf_t* iob, size_t n) {
    iob->io_base += n;
    iob->io_off += n;
    iob->io_resid -= n;
}